package com.dotmedia.dboperations;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.dotmedia.core.DatabaseAccessService;
import com.dotmedia.entities.Permission;
import com.dotmedia.entities.PermissionGroup;

public class PermissionDatabaseOperations {
	private static Logger logger = Logger.getLogger("PermissionDatabaseOperations");

	/**
	 * This method persists the Permission Entity which is passed to this method
	 * 
	 * @param permissionEntity
	 *        The permission entity which is to be persisted
	 */
	public void persistPermissionEntity(Permission permissionEntity) {
		DatabaseAccessService databaseAccessService = DatabaseAccessService.getInstance();
		int persistReturnStatus = databaseAccessService.persistEntity(permissionEntity);
		if (persistReturnStatus == 0) {
			logger.info("The Permission Entitiy with id = " + permissionEntity.getPermissionExtId() + " was successfully persisted into the database");
		} else {
			logger.error("The Permission Entity with id = " + permissionEntity.getPermissionExtId() + " cannot be persisted into the database");
		}
	}

	/**
	 * This method removes a Permission Entity from the database which is passed to it
	 * 
	 * @param permissionEntity
	 *        The Permission Entity which is to be removed from the database
	 */
	public void removePermissionEntity(Permission permissionEntity) {
		DatabaseAccessService databaseAccessService = DatabaseAccessService.getInstance();
		logger.info("Removing a Permission Entity with the id = " + permissionEntity.getId());
		int removeReturnStatus = databaseAccessService.removeEntity(permissionEntity, permissionEntity.getId().intValue());
		if (removeReturnStatus == 0) {
			logger.info("The Permission Entity with id = " + permissionEntity.getPermissionExtId() + " was successfully removed from the database");
		} else {
			logger.error("The Permission Entity with id = " + permissionEntity.getPermissionExtId() + " cannot be removed from the database");
		}
	}

	/**
	 * This method updates a permission entity. A permission entity is identified uniquely by the permissionExtId so this method searches on that
	 * member of the Permission class. All the members of the class will be updated except id and permissionExtId which will remain the same.
	 * 
	 * @param permissionEntity
	 *        The permission entity which needs to be updated.
	 */
	public void updatePermissionEntity(Permission permissionEntity) {
		String query = "SELECT permissionEntity FROM Permission permissionEntity where permissionEntity.permissionExtId = '"
				+ permissionEntity.getPermissionExtId() + "'";
		DatabaseAccessService databaseAccessService = DatabaseAccessService.getInstance();
		List retrievedEntities = databaseAccessService.getEntities(query);
		boolean updated = false;
		for (int retrievedEntitiesIndex = 0; retrievedEntitiesIndex < retrievedEntities.size(); retrievedEntitiesIndex++) {
			Permission currentPermissionEntity = (Permission) retrievedEntities.get(retrievedEntitiesIndex);
			if (currentPermissionEntity.getPermissionExtId().equals(permissionEntity.getPermissionExtId())) {
				// this is the entity which needs to be updated
				currentPermissionEntity.setDescription(permissionEntity.getDescription());
				currentPermissionEntity.setNotes(permissionEntity.getNotes());
				currentPermissionEntity.setPermissionGroup(permissionEntity.getPermissionGroup());
				logger.info("Updating a Permission entity with permissionExtId = " + currentPermissionEntity.getPermissionExtId());
				int updateStatus = databaseAccessService.updateEntity(currentPermissionEntity);
				if (updateStatus == 0) {
					logger.info("The Permission entity was successfully updated");
					updated = false;
				} else {
					logger.error("The Permission entity was not successfully updated.");
				}
				break;
			}
		}
		if (!updated) {
			logger.warn("The Permission Entity was not updated. Could not be found or some error occurred while updating");
		}
	}

	/**
	 * This method returns a list of entities with a given permissionExtId. There will be only one such entity if the database is consistent
	 * 
	 * @param permissionExtId
	 *        The permissionExtId whose entities needs to be returned
	 * @return A List of Permission entities matching the permissionExtId
	 */
	public List<Permission> getPermissionEntitiesWithExtId(String permissionExtId) {
		List<Permission> toReturnEntities = new ArrayList<Permission>();
		String query = "SELECT permissionEntity FROM Permission permissionEntity where permissionEntity.permissionExtId = '" + permissionExtId + "'";
		DatabaseAccessService databaseAccessService = DatabaseAccessService.getInstance();
		List retrievedEntities = databaseAccessService.getEntities(query);
		for (int retrivedEntitiesIndex = 0; retrivedEntitiesIndex < retrievedEntities.size(); retrivedEntitiesIndex++) {
			Permission currentPermissionEntity = (Permission) retrievedEntities.get(retrivedEntitiesIndex);
			toReturnEntities.add(currentPermissionEntity);
		}
		return toReturnEntities;
	}

	/**
	 * This method returns a list of Permission entities which belong to a particular permissionGroup.
	 * 
	 * @param permissionGroupEntity
	 *        The permissionGroup entity to which the Permission entity belongs to.
	 * @return The list of the Permission entity.
	 */
	public List<Permission> getPermissionEntitiesWithPermissionGroup(PermissionGroup permissionGroupEntity) {
		List<Permission> toReturnEntities = new ArrayList<Permission>();
		String query = "SELECT permissionEntity FROM Permission permissionEntity where permissionEntity.permissionGroup.id = "
				+ permissionGroupEntity.getId();
		DatabaseAccessService databaseAccessService = DatabaseAccessService.getInstance();
		List retrievedEntities = databaseAccessService.getEntities(query);
		for (int retrievedEntitiesIndex = 0; retrievedEntitiesIndex < retrievedEntities.size(); retrievedEntitiesIndex++) {
			Permission currentPermissionEntity = (Permission) retrievedEntities.get(retrievedEntitiesIndex);
			toReturnEntities.add(currentPermissionEntity);
		}
		return toReturnEntities;
	}

	/**
	 * This method returns the permission group mappings with permissions
	 * 
	 * @return A map with the mappings of permission groups with permission
	 */
	public Map<String, List<Permission>> getPermissionGroupMappingWithPermission() {
		logger.info("IN method getPermissionGroupMappingWithPermission() in PermissionDatabaseOperations");
		Map<String, List<Permission>> returnMap = new HashMap<String, List<Permission>>();
		// get all permission groups
		PermissionGroupDatabaseOperations permissionGroupDatabaseOperations = new PermissionGroupDatabaseOperations();
		List<PermissionGroup> allPermissionGroups = permissionGroupDatabaseOperations.getAllPermissionGroupEntities();
		for (int permissionGroupIndex = 0; permissionGroupIndex < allPermissionGroups.size(); permissionGroupIndex++) {
			PermissionGroup currentPermissionGroup = allPermissionGroups.get(permissionGroupIndex);
			// get all permission entities for this permission group
			List<Permission> allPermissions = getPermissionEntitiesWithPermissionGroup(currentPermissionGroup);
			if (allPermissions.size() > 0) {
				// include this permission group else not
				returnMap.put(currentPermissionGroup.getDescription(), allPermissions);
			}
		}
		logger.info("OUT method getPermissionGroupMappingWithPermision() in PermissionDatabaseOperations");
		return returnMap;
	}
}
